package cn.sz.hy.logic.strategy.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jxl.Cell;
import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import cn.sz.hy.common.Globel;
import cn.sz.hy.logic.strategy.vo.BasicVo;
import cn.sz.hy.logic.strategy.vo.SheetItem;
import cn.sz.hy.logic.strategy.vo.TableVo;

public class InsertStrategy extends XlsStrategy
{

    private WritableWorkbook detWorkbook;
    private WritableSheet writableSheet;

    @Override
    public boolean execute(BasicVo entity)
    {
        initDet(entity);
        this.backup = eBus.getTableVo(Globel.BACKUP);
        
        Map<String, Cell[]> backDate = loadAllRows(backup);
        if(backDate == null){
        	return false;
        }
        Sheet mainSheet = main.getSheet();
        int rowCount = mainSheet.getRows();
        Integer[] mainKeys = main.getKeyArray();

        insertHeader();
        for (int i = 1; i < rowCount; i++)
        {
            Cell[] mainCells = mainSheet.getRow(i);
            String key = getKey(mainKeys, mainCells);
            Cell[] backupCells = backDate.get(key);

            // int[][] detColumnMaping = getDetColumnMapping();

            List<SheetItem> detItems = det.getColumns();
            for (int j = 0; j < detItems.size(); j++)
            {
                // int[] mapCell = detColumnMaping[j];
                SheetItem item = detItems.get(j);
//                TableVo parent = item.getPatent();
                Cell cell = null;
                
                if (item.getLinkType() == Globel.KEY_LINK || item.getLinkType() == Globel.NONE_LINK)
                {
                    cell = mainCells[item.getColumn()];
                }
                else if (item.getLinkType() == Globel.INSERT_LINK)
                {
                    if (backupCells != null)
                    {
                        cell = backupCells[item.getColumn()];
                    }
                }
                try
                {
                    writableSheet.addCell(getWriTableCell(i, j, cell));
                } catch (RowsExceededException e)
                {
                    e.printStackTrace();
                    return false;
                } catch (WriteException e)
                {
                    e.printStackTrace();
                    return false;
                }
            }
        }
        try
        {
            detWorkbook.write();
        } catch (IOException e)
        {
            e.printStackTrace();
            return false;
        }
        close();
        return true;
    }

    private WritableCell getWriTableCell(int row, int col, Cell cell)
    {
        if (cell == null)
            return new Label(col, row, "");
        CellType type = cell.getType();
        if (type == CellType.NUMBER || type == CellType.NUMBER_FORMULA)
        {
            return new Number(col, row, new Double(cell.getContents()), cell
                    .getCellFormat());
        }
        else
        {
            return new Label(col, row, cell.getContents(), cell.getCellFormat());
        }
        // if (type == CellType.DATE || type == CellType.DATE_FORMULA)
    }

    private void insertHeader()
    {
        try
        {
            List<SheetItem> items = det.getColumns();
            WritableFont wf = new WritableFont(WritableFont.TIMES, 10,
                    WritableFont.NO_BOLD, false);// ���һ��Ϊ�Ƿ�italic
            WritableCellFormat format = new WritableCellFormat(wf);
            Label label;
            for (int i = 0; i < items.size(); i++)
            {
                SheetItem item = items.get(i);
                label = new Label(i, 0, item.getName(), format);
                writableSheet.addCell(label);
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private void initDet(BasicVo entity)
    {
        File file = new File(entity.getDet());
        try
        {
            detWorkbook = Workbook.createWorkbook(file);
            writableSheet = detWorkbook.createSheet("sheet1", 0);
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.main = eBus.getTableVo(Globel.MAIN);
        for(SheetItem item : entity.getDetColumn()){
        	if(Globel.KEY_LINK == item.getLinkType()){
        		this.main.setKeyArray(item.getPatent().getKeyArray());
        		break;
        	}
        }
        det = new TableVo(entity.getDetColumn(), writableSheet, "sheet1");
    }

    public Map<String, Cell[]> loadAllRows(TableVo header)
    {
        Sheet sheet = header.getSheet();
        int len = sheet.getRows();
        Integer[] keys = header.getKeyArray();
        if(keys.length == 0) {
        	return null;
        }
        Map<String, Cell[]> rows = new HashMap<String, Cell[]>();

        for (int i = header.row + 1; i < len; i++)
        {
            Cell[] cells = sheet.getRow(i);
            String key = getKey(keys, cells);
            rows.put(key, cells);
        }

        return rows;
    }

    private String getKey(Integer[] keys, Cell[] cells)
    {
        String key = "";
        for (int index : keys)
        {
            key += cells[index].getContents();
        }
        return key;
    }

    public static void main(String[] args)
    {
        InsertStrategy is = new InsertStrategy();
        BasicVo be = new BasicVo();
        be.setSrc1("F:/test/��ͨ��4��ǰ.xls");
        be.setSrc2("F:/test/5��.xls");
        be.setDet("F:/test/det.xls");
        be.setSheetIndex(0);
        List<TableVo> src1 = is.loadHeader(be.getSrc1());
        List<TableVo> src2 = is.loadHeader(be.getSrc2());

        TableVo main = src1.get(0);
        TableVo backup = src2.get(0);

        backup.getColumns().get(0).setMappingItem(main.getColumns().get(0),
                Globel.KEY_LINK);

        List<SheetItem> columns = new ArrayList<SheetItem>();
        for (SheetItem item : main.getColumns())
        {
            SheetItem detItem = new SheetItem(item.getName(), item.getColumn(),
                    Globel.INSERT_LINK, item);
            columns.add(detItem);
        }
        SheetItem bu = backup.getColumns().get(2);
        SheetItem detItem = new SheetItem(bu.getName(), bu.getColumn(),
                Globel.INSERT_LINK, bu);
        
        columns.add(3, detItem);
        be.setDetColumn(columns);
        eBus.addTableVo(Globel.MAIN, main);
        eBus.addTableVo(Globel.BACKUP, backup);
        is.execute(be);
    }


    public void close()
    {
        super.close();
        try
        {
            detWorkbook.close();
        } catch (WriteException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

}
